package com.xpec.c4.codec.amf0;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.nio.ByteBuffer;

import com.xpec.c4.codec.Codec;

import flex.messaging.io.SerializationContext;
import flex.messaging.io.amf.Amf0Input;
import flex.messaging.io.amf.Amf0Output;

/**
 * 使用AMF方式，进行对象编码与解码
 * 
 * @author lipeilin
 * 
 */
public class Amf0Codec implements Codec {

	@Override
	public Object decode(ByteBuffer byteBuffer) throws Exception {

		byte[] bytes = new byte[byteBuffer.remaining()];
		byteBuffer.get(bytes);

		decodeByte(bytes);

		return decodeByte(bytes);
	}

	@Override
	public ByteBuffer encode(Object obj) throws Exception {

		byte[] messageBytes = encodeByte(obj);
		ByteBuffer buffer = ByteBuffer.allocate(messageBytes.length);
		buffer.put(messageBytes);
		buffer.flip();

		return buffer;
	}

	@Override
	public byte[] encodeEx(Object obj) throws Exception {

		byte[] messageBytes = encodeByte(obj);
		return messageBytes;
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see com.xpec.c4.codec.Codec#decodeByte(byte[])
	 */
	@Override
	public Object decodeByte(byte[] byteBuffer) throws Exception {
		SerializationContext serializationContext = new SerializationContext();
		serializationContext.legacyCollection = true;

		// 序列化amf3对象
		Amf0Input amfout = new Amf0Input(serializationContext);

		InputStream is = new ByteArrayInputStream(byteBuffer);

		amfout.setInputStream(is);

		Object obj = amfout.readObject();

		amfout.close();
		
		return obj;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.xpec.c4.codec.Codec#encodeByte(java.lang.Object)
	 */
	@Override
	public byte[] encodeByte(Object obj) throws Exception {
		SerializationContext serializationContext = new SerializationContext();
		serializationContext.legacyCollection = true;

		// 序列化amf3对象
		Amf0Output amfout = new Amf0Output(serializationContext);

		// 实现了一个输出流，其中的数据被写入一个 byte 数组。
		ByteArrayOutputStream byteoutStream = new ByteArrayOutputStream();

		// 将byteoutStream产生的数组流导入到DataOutputStream流中
		DataOutputStream dataoutstream = new DataOutputStream(byteoutStream);

		// 设置流的编码格式为amf3
		amfout.setOutputStream(dataoutstream);

		amfout.writeObject(obj);// 实际上是将map对象写入到dataoutstream流中
		dataoutstream.flush();// 清空缓存

		// 将ByteArrayOutputStream流中转化成字节数组
		byte[] messageBytes = byteoutStream.toByteArray();// amf3数据
		
		amfout.close();

		return messageBytes;
	}

}
